home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / etc / init.d / halt.sh < prev    next >
Text File  |  2005-10-16  |  7KB  |  255 lines

  1. # Copyright 1999-2005 Gentoo Foundation
  2. # Distributed under the terms of the GNU General Public License v2
  3.  
  4. # Check to see if this is a livecd, if it is read the commandline
  5. # this mainly makes sure $CDBOOT is defined if it's a livecd
  6. [[ -f /sbin/livecd-functions.sh ]] && \
  7.     source /sbin/livecd-functions.sh && \
  8.     livecd_read_commandline
  9.  
  10. # livecd-functions.sh should _ONLY_ set this differently if CDBOOT is
  11. # set, else the default one should be used for normal boots.
  12. # say:  RC_NO_UMOUNTS="/newroot|/memory|/mnt/cdrom|/mnt/livecd"
  13. RC_NO_UMOUNTS=${RC_NO_UMOUNTS:-/newroot|/memory}
  14.  
  15. RC_NO_UMOUNT_FS="^(proc|devpts|sysfs|devfs|tmpfs|usb(dev)?fs|unionfs)$"
  16.  
  17. # Reset pam_console permissions if we are actually using it
  18. if [[ -x /sbin/pam_console_apply && ! -c /dev/.devfsd && \
  19.       -n $(grep -v -e '^[[:space:]]*#' /etc/pam.d/* | grep 'pam_console') ]]; then
  20.     /sbin/pam_console_apply -r
  21. fi
  22.  
  23. # We need to properly terminate devfsd to save the permissions
  24. if [[ -n $(ps --no-heading -C 'devfsd') ]]; then
  25.     ebegin "Stopping devfsd"
  26.     killall -15 devfsd &>/dev/null
  27.     eend $?
  28. elif [[ ! -e /dev/.devfsd && -e /dev/.udev && -z ${CDBOOT} && \
  29.         ${RC_DEVICE_TARBALL} == "yes" ]] && \
  30.         touch /lib/udev-state/devices.tar.bz2 2>/dev/null
  31. then
  32.     ebegin "Saving device nodes"
  33.     # Handle our temp files
  34.     devices_udev=$(mktemp /tmp/devices.udev.XXXXXX)
  35.     devices_real=$(mktemp /tmp/devices.real.XXXXXX)
  36.     devices_totar=$(mktemp /tmp/devices.totar.XXXXXX)
  37.     device_tarball=$(mktemp /tmp/devices-XXXXXX)
  38.     
  39.     if [[ -z ${devices_udev} || -z ${devices_real} || \
  40.           -z ${device_tarball} ]]; then
  41.         eend 1 "Could not create temporary files!"
  42.     else
  43.         cd /dev
  44.         # Find all devices
  45.         find . -xdev -type b -or -type c -or -type l | cut -d/ -f2- > \
  46.             "${devices_real}"
  47.         # Figure out what udev created
  48.         eval $(grep '^[[:space:]]*udev_db=' /etc/udev/udev.conf)
  49.         if [[ -d ${udev_db} ]]; then
  50.             # New udev_db is clear text ...
  51.             udevinfo=$(cat "${udev_db}"/*)
  52.         else
  53.             # Old one is not ...
  54.             udevinfo=$(udevinfo -d)
  55.         fi
  56.         # This basically strips 'S:' and 'N:' from the db output, and then
  57.         # print all the nodes/symlinks udev created ...
  58.         echo "${udevinfo}" | gawk '
  59.             /^(N|S):.+/ {
  60.                 sub(/^(N|S):/, "")
  61.                 split($0, nodes)
  62.                 for (x in nodes)
  63.                     print nodes[x]
  64.             }' > "${devices_udev}"
  65.         # These ones we also do not want in there
  66.         for x in MAKEDEV core fd initctl pts shm stderr stdin stdout; do
  67.             echo "${x}" >> "${devices_udev}"
  68.         done
  69.         fgrep -x -v -f "${devices_udev}" < "${devices_real}" > "${devices_totar}"
  70.         # Now only tarball those not created by udev if we have any
  71.         if [[ -s ${devices_totar} ]]; then
  72.             try tar -jclpf "${device_tarball}" -T "${devices_totar}"
  73.             try mv -f "${device_tarball}" /lib/udev-state/devices.tar.bz2
  74.             try rm -f "${devices_udev}" "${devices_real}"
  75.         else
  76.             rm -f /lib/udev-state/devices.tar.bz2
  77.         fi
  78.         eend 0
  79.     fi
  80. fi
  81.  
  82. # Try to unmount all tmpfs filesystems not in use, else a deadlock may
  83. # occure, bug #13599.
  84. umount -at tmpfs &>/dev/null
  85.  
  86. if [[ -n $(swapon -s 2>/dev/null) ]]; then
  87.     ebegin "Deactivating swap"
  88.     swapoff -a
  89.     eend $?
  90. fi
  91.  
  92. # Write a reboot record to /var/log/wtmp before unmounting
  93.  
  94. halt -w &>/dev/null
  95.  
  96. # Unmounting should use /proc/mounts and work with/without devfsd running
  97.  
  98. # Credits for next function to unmount loop devices, goes to:
  99. #
  100. #    Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
  101. #    Modified for RHS Linux by Damien Neil
  102. #
  103. #
  104. # Unmount file systems, killing processes if we have to.
  105. # Unmount loopback stuff first
  106. # Use `umount -d` to detach the loopback device
  107.  
  108. # Remove loopback devices started by dm-crypt
  109.  
  110. remaining=$(awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts | \
  111.             sort -r | egrep -v "^(${RC_NO_UMOUNTS})$")
  112. [[ -n ${remaining} ]] && {
  113.     sig=
  114.     retry=1
  115.  
  116.     while [[ -n ${remaining} && ${retry} -gt 0 ]]; do
  117.         if [[ ${retry} -lt 3 ]]; then
  118.             #ebegin "Unmounting loopback filesystems (retry)"
  119.             umount -d ${remaining} &>/dev/null
  120.             #eend $? "Failed to unmount filesystems this retry"
  121.         else
  122.             #ebegin "Unmounting loopback filesystems"
  123.             umount -d ${remaining} &>/dev/null
  124.             #eend $? "Failed to unmount filesystems"
  125.         fi
  126.  
  127.         remaining=$(awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts | \
  128.                     sort -r | egrep -v "^(${RC_NO_UMOUNTS})$")
  129.         [[ -z ${remaining} ]] && break
  130.         
  131.         /bin/fuser -k -m ${sig} ${remaining} &>/dev/null
  132.         sleep 5
  133.         retry=$((${retry} - 1))
  134.         sig=-9
  135.     done
  136. }
  137.  
  138. # Try to unmount all filesystems (no /proc,tmpfs,devfs,etc).
  139. # This is needed to make sure we dont have a mounted filesystem 
  140. # on a LVM volume when shutting LVM down ...
  141. ebegin "Unmounting filesystems"
  142. unmounts=$(awk -v NO_UMOUNT_FS="${RC_NO_UMOUNT_FS}" \
  143.     '{ \
  144.         if (($3 !~ NO_UMOUNT_FS) && \
  145.             ($1 != "none") && \
  146.             ($1 !~ /^(rootfs|\/dev\/root)$/) && \
  147.             ($2 != "/")) \
  148.           print $2 \
  149.     }' /proc/mounts | sort -ur)
  150. for x in ${unmounts}; do
  151.     # Do not umount these ... will be different depending on value of CDBOOT
  152.     if [[ -n $(echo "${x}" | egrep "^(${RC_NO_UMOUNTS})$") ]] ; then
  153.         continue
  154.     fi
  155.  
  156.     x=${x//\\040/ }
  157.     if ! umount "${x}" &>/dev/null; then
  158.         # Kill processes still using this mount
  159.         /bin/fuser -k -m -9 "${x}" &>/dev/null
  160.         sleep 2
  161.         # Now try to unmount it again ...
  162.         umount -f -r "${x}" &>/dev/null
  163.     fi
  164. done
  165. eend 0
  166.  
  167. # Try to remove any dm-crypt mappings
  168. stop_addon dm-crypt
  169.  
  170. # Stop LVM, etc
  171. stop_volumes
  172.  
  173. # This is a function because its used twice below
  174. ups_kill_power() {
  175.     local UPS_CTL UPS_POWERDOWN
  176.     if [[ -f /etc/killpower ]] ; then
  177.         UPS_CTL=/sbin/upsdrvctl
  178.         UPS_POWERDOWN="${UPS_CTL} shutdown"
  179.     elif [[ -f /etc/apcupsd/powerfail ]] ; then
  180.         UPS_CTL=/etc/apcupsd/apccontrol
  181.         UPS_POWERDOWN="${UPS_CTL} killpower"
  182.     else
  183.         return 0
  184.     fi
  185.     if [[ -x ${UPS_CTL} ]] ; then
  186.         ewarn "Signalling ups driver(s) to kill the load!"
  187.         ${UPS_POWERDOWN}
  188.         ewarn "Halt system and wait for the UPS to kill our power"
  189.         /sbin/halt -id
  190.         while [ 1 ]; do sleep 60; done
  191.     fi
  192. }
  193.  
  194. mount_readonly() {
  195.     local x=
  196.     local retval=0
  197.     local cmd=$1
  198.  
  199.     # Get better results with a sync and sleep
  200.     sync; sync
  201.     sleep 1
  202.  
  203.     for x in $(awk -v NO_UMOUNT_FS="${RC_NO_UMOUNT_FS}" \
  204.                    '{ \
  205.                        if (($1 != "none") && ($3 !~ NO_UMOUNT_FS)) \
  206.                            print $2 \
  207.                    }' /proc/mounts | sort -ur) ; do
  208.         x=${x//\\040/ }
  209.         if [[ -n $(echo "${x}" | egrep "^(${RC_NO_UMOUNTS})$") ]] ; then
  210.             continue
  211.         fi
  212.         if [[ ${cmd} == "u" ]]; then
  213.             umount -n -r "${x}" &>/dev/null
  214.         else
  215.             mount -n -o remount,ro "${x}" &>/dev/null
  216.         fi
  217.         retval=$((${retval} + $?))
  218.     done
  219.     [[ ${retval} -ne 0 ]] && killall5 -9 &>/dev/null
  220.  
  221.     return ${retval}
  222. }
  223.  
  224. # Since we use `mount` in mount_readonly(), but we parse /proc/mounts, we 
  225. # have to make sure our /etc/mtab and /proc/mounts agree
  226. cp /proc/mounts /etc/mtab &>/dev/null
  227. ebegin "Remounting remaining filesystems readonly"
  228. mount_worked=1
  229.         # If these things really don't want to remount ro, then 
  230.         # let's try to force them to unmount
  231.         if ! mount_readonly u ; then
  232.             mount_worked=1
  233.         fi
  234. eend ${mount_worked}
  235. eject &>/dev/null
  236. sleep 3
  237.  
  238. if [[ ${mount_worked} -eq 1 ]]; then
  239.     ups_kill_power
  240. fi
  241.  
  242. # Inform if there is a forced or skipped fsck
  243. if [[ -f /fastboot ]]; then
  244.     echo
  245.     ewarn "Fsck will be skipped on next startup"
  246. elif [[ -f /forcefsck ]]; then
  247.     echo
  248.     ewarn "A full fsck will be forced on next startup"
  249. fi
  250.  
  251. ups_kill_power
  252.  
  253.  
  254. # vim:ts=4
  255.